#include <list>
#include <string>

//////////////////////////////////////////////////
//ResourceManager
//////////////////////////////////////////////////

template <class Type> class ResourceManager
  {
  public:
    ResourceManager();    
	  ~ResourceManager();

  private:
    std::list<Type*>* m_list_of_loaded_resources;

  public:
    Type* AddResource(std::string i_path, std::string i_name);
    Type* GetResource(std::string i_path, std::string i_name, bool i_load = false);
    void RemoveResource(Type* i_resource);
    unsigned long GetNumberOfResources();
    void EmptyList();
    
  private:

  };

//////////////////////////////////////////////////

//////////////////////////////////////////////////
//ResourceManager
//////////////////////////////////////////////////

//------------------------------------------------

template <class Type> ResourceManager<Type>::ResourceManager()
  {
  m_list_of_loaded_resources = new std::list<Type*>();
  }

//------------------------------------------------

template <class Type> ResourceManager<Type>::~ResourceManager()
  {  
  EmptyList();
  delete m_list_of_loaded_resources;
  }

//------------------------------------------------

template <class Type> Type* ResourceManager<Type>::AddResource(std::string i_path, std::string i_name)
  {
  if( i_path.empty() || i_name.empty())
    {
			return NULL;
    }
  Type* type = GetResource(i_path, i_name, false);
  if(type)
    {
    type->AddReference();
    return type;
    }
  else
    {
    type = new Type(i_path, i_name);
    m_list_of_loaded_resources->push_back(type);
    return type;
    }
  }

//------------------------------------------------

template <class Type> Type* ResourceManager<Type>::GetResource(std::string i_path, std::string i_name, bool i_load)
  {
  if( i_path.empty() || i_name.empty() || m_list_of_loaded_resources == NULL || m_list_of_loaded_resources->empty())
    {
			return NULL;
    }

  std::list<Type*>::iterator resource_iterator;
  for(resource_iterator = m_list_of_loaded_resources->begin(); resource_iterator != m_list_of_loaded_resources->end(); resource_iterator++)
    {
    if(*resource_iterator != NULL)
      {
      if((*resource_iterator)->GetPath() == i_path)
        {
        if((*resource_iterator)->GetName() == i_name)
          {
          return *resource_iterator;
          }
        }
      }
    }
  if(i_load)
    {
    return AddResource(i_path, i_name);
    }
  else
    {
    return NULL;
    }
  }

//------------------------------------------------

template <class Type> void ResourceManager<Type>::RemoveResource(Type* i_resource)
  {
  if(i_resource == NULL)
    {
    return;
    }

  std::list<Type*>::iterator resource_iterator;
  for(resource_iterator = m_list_of_loaded_resources->begin(); resource_iterator != m_list_of_loaded_resources->end(); resource_iterator++)
    {
    if(*resource_iterator != NULL)
      {
      if((*resource_iterator)->GetPath() == i_resource->GetPath())
        {
        if((*resource_iterator)->GetName() == i_resource->GetName())
          {
          (*resource_iterator)->RemoveReference();
          if((*resource_iterator)->GetNbOfReferences() == 0)
            {
            m_list_of_loaded_resources->remove(*resource_iterator);
            return;
            }
          }
        }
      }
    }
  }

//------------------------------------------------

template <class Type> unsigned long ResourceManager<Type>::GetNumberOfResources()
	{
  unsigned long number_of_elements = 0;
  for(std::list<Type*>::iterator i = m_list_of_loaded_resources->begin(); i != m_list_of_loaded_resources->end(); i++)
    {
	  number_of_elements++;
    }
    return number_of_elements;
	}

//------------------------------------------------

template <class Type> void ResourceManager<Type>::EmptyList()
	{
	for(std::list<Type*>::iterator i = m_list_of_loaded_resources->begin(); i != m_list_of_loaded_resources->end(); i++)
    {
		delete *i
    }

  m_list_of_loaded_resources->empty();    
	}

//------------------------------------------------

//////////////////////////////////////////////////